package com.dao;

import java.io.UnsupportedEncodingException;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.base.BaseAction;
import com.base.BaseDao;
import com.bean.RulerInfo;
import com.bean.RulerMethod;
import com.bean.RulerRole;
import com.util.GUtil;

@SuppressWarnings("unchecked")
public class RulerDao extends BaseDao {
	
	private static final Logger log = Logger.getLogger(RulerDao.class);
	
	public List<RulerInfo> listTreeRuler() {

		Session session =this.getSession();
		Query query = session.createQuery(" from RulerInfo where status=1 ");
		List<RulerInfo> list = (List<RulerInfo>)query.list();
		//先按菜单级别排序
		Collections.sort(list, new Comparator<RulerInfo>() {
			@Override
			public int compare(RulerInfo r1, RulerInfo r2) {
				return r1.getLevel() - r2.getLevel();
			}
		});
		//再按order排序
		Collections.sort(list, new Comparator<RulerInfo>() {
			@Override
			public int compare(RulerInfo r1, RulerInfo r2) {
				return r1.getSortorder() - r2.getSortorder();
			}
		});
		return list;
	}
	/**
	 * 获取某个角色的菜单
	 * @param list2
	 * @return
	 */
	public List<RulerInfo> rulerList(List<Integer> list2){
		
		Long t1 = System.currentTimeMillis();
		
		Session session =this.getSession();
		Query query = session.createQuery(" from RulerInfo p where p.rulerid in (:list2) and p.status!=-1  order by id ");// and p.echo=1
		query.setParameterList("list2", list2);
		List<RulerInfo> list = (List<RulerInfo>)query.list();
	
		Long t2 = System.currentTimeMillis();
		
		//先按菜单级别排序
		Collections.sort(list, new Comparator<RulerInfo>() {
			@Override
			public int compare(RulerInfo r1, RulerInfo r2) {
				return r1.getLevel() - r2.getLevel();
			}
		});
		//再按order排序
		Collections.sort(list, new Comparator<RulerInfo>() {
			@Override
			public int compare(RulerInfo r1, RulerInfo r2) {
				return r1.getSortorder() - r2.getSortorder();
			}
		});
		Long t3 = System.currentTimeMillis();
		
		log.info(" RulerDao.rulerList total takes "+(t3-t1)+"ms"+" [query takes "+(t2-t1)+"ms] [sort takes "+(t3-t2)+"ms]");
		
		return  list;
	}

	//根据角色ID获取所有权限/菜单
	public List<RulerRole> rulerRole(int roleid){
		Long t1 = System.currentTimeMillis();
		List< RulerRole> list = null;
		Session session =this.getSession();
		Long t2 = System.currentTimeMillis();
		
		//根据roleid获取List<RuelrRole>
		Query query = session.createQuery(" from RulerRole r where r.roleId=?");
		query.setInteger(0, roleid);
		list = (List< RulerRole>)query.list();
		Long t3 = System.currentTimeMillis();
		
		log.info(" RulerDao.rulerRole takes total "+(t3-t1)+"ms [query takes "+(t3-t2)+"ms] ");
		return list;
	}

	/**
	 * 根据 action 获取 RulerInfo
	 * <p>Title: getByAction</p>
	 * <p>Description: </p>
	 * @param action
	 * @return
	 */
	public RulerInfo getByAction(String action) {
		Session session = this.getSession();
		String hql="from RulerInfo where status=1 ";
		if(action!=null ){
			if( !action.trim().isEmpty() ){
				hql += " and url=?"; 
				Query query = session.createQuery(hql);
				query.setString(0, action);
				query.setMaxResults(1);
				return (RulerInfo) query.uniqueResult();
			}
		}
		return null;
	}

	/**
	 * 获取所有菜单
	 * <p>Title: list</p>
	 * <p>Description: 
	 * 		不进行排序和子菜单识别
	 * </p>
	 * @param rulerInfo
	 * @return
	 */
	public List<RulerInfo> list(RulerInfo rulerInfo) {
		Session session = this.getSession();
		String hql="from RulerInfo where status=1 ";
		Query query = session.createQuery(hql);
		return query.list();
	}
	
	/**
	 * 获取 RulerMethod列表 
	 * <p>Title: queryMethds</p>
	 * <p>Description: </p>
	 * @param rulerMethod
	 * @param bmap : true 去除重复 group by method | false 查询所有
	 * @return
	 */
	public List<RulerMethod> queryMethds(RulerMethod rulerMethod, boolean bmap){
		List<RulerMethod> list = null;
		Session session = this.getSession();
		if(bmap )
			list = session.createQuery("From RulerMethod group by method").list();
		else
			list = session.createQuery("From RulerMethod ").list();
		return list;
	}
	
	public List<RulerRole> queryMyRuler(int roleId){
		Session session = this.getSession();
		String hql="from RulerRole where roleId=? ";
		Query query = session.createQuery(hql);
		query.setInteger(0, roleId);
		Long t1 = System.currentTimeMillis();
		List<RulerRole> listTemp= (List<RulerRole>)query.list();//query RulerInfo
		Long t2 = System.currentTimeMillis();
		
		log.info("RulerDao.queryMyRuler: [query List<RulerInfo> takes "+(t2-t1)+"ms]");
		
		return listTemp;
	}
	
	/**
	 * 获取所有菜单
	 * <p>Title: query</p>
	 * <p>Description:
	 * 		1. 子菜单检索
	 * 		2. 进行排序	
	 * </p>
	 * @param rulerInfo
	 * @return
	 */
	public List<RulerInfo> query(RulerInfo rulerInfo) {
		Session session = this.getSession();
		String hql="from RulerInfo where status=1 ";
		if(rulerInfo!=null ){
			if( rulerInfo.getRulerName()!=null && !rulerInfo.getRulerName().trim().isEmpty())
				hql += " and rulerName like '%"+rulerInfo.getRulerName().trim()+"%' ";
			if( rulerInfo.getUrl()!=null && !rulerInfo.getUrl().trim().isEmpty() )
				hql += " and url like '%"+rulerInfo.getUrl()+"%' "; 
		}
		Query query = session.createQuery(hql);
		
		Long t1 = System.currentTimeMillis();
		List<RulerInfo> listTemp= (List<RulerInfo>)query.list();//query RulerInfo
		
		Long t2 = System.currentTimeMillis();
		List<RulerMethod > listRulerMethod = session.createQuery("from RulerMethod order by method ").list();//query RulerMethods
		Long t3 = System.currentTimeMillis();
		
		//给RulerInfo设置methods
		List<RulerMethod> methods = null;
		for(RulerInfo ri : listTemp){
			methods = new ArrayList<RulerMethod>();
			for(RulerMethod rm : listRulerMethod){
				if( (rm.getRulerId()-ri.getRulerid()==0) ){
					methods.add(rm);
				}
			}
			if(methods!=null)
				ri.setMethods(methods);
		}
		Long t4 = System.currentTimeMillis();

		List<RulerInfo> list = new ArrayList<RulerInfo>();
		if(listTemp!=null && listTemp.size()>1){
			for(RulerInfo r : listTemp){
				if(r.getLevel()==1){
					list.add(r);
					for(RulerInfo r2 : listTemp){
						if(r2.getLevel()==2 && r2.getManager()==r.getRulerid())
							r.getSubRulerList().add(r2);
					}
					//再按order排序第二级
					Collections.sort( r.getSubRulerList(), new Comparator<RulerInfo>() {
						@Override
						public int compare(RulerInfo r1, RulerInfo r2) {
							return r1.getSortorder() - r2.getSortorder();
						}
					});
				}
			}
			//再按order排序第一级
			Collections.sort( list, new Comparator<RulerInfo>() {
				@Override
				public int compare(RulerInfo r1, RulerInfo r2) {
					return r1.getSortorder() - r2.getSortorder();
				}
			});
		}
		Long t5 = System.currentTimeMillis();
		
		log.info("RulerDao.query: [query List<RulerInfo> takes "+(t2-t1)+"ms] [query List<RulerMethod> takes "+(t3-t2)+"ms] " +
				"[setMethods takes "+(t4-t3)+"ms] [sort takes "+(t5-t4)+"ms] ");
		
		return list;
	}

	DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
	public String delete(int id) {

		Session session = this.getSession();
		RulerInfo r = new RulerInfo();
		r.setRulerid(id);
		session.delete(r);
		session.flush();
		return GUtil.SUCCESS;
	}

	public RulerInfo get(int id) {

		Session session = this.getSession();
		Query query = session.createQuery("from RulerInfo where rulerid=:rulerid");
		query.setParameter("rulerid", id);
		RulerInfo  rulerInfo = (RulerInfo) query.uniqueResult();
		if(rulerInfo!=null){

			query = session.createQuery("from RulerMethod where rulerId=?");
			query.setInteger(0, rulerInfo.getRulerid());
			List methods = query.list();
			if(methods!=null)
				rulerInfo.setMethods(methods);

			if(rulerInfo.getManager()!=null && rulerInfo.getManager()>0){
				RulerInfo m = (RulerInfo) session.get(RulerInfo.class, rulerInfo.getManager());
				if(m!=null){
					rulerInfo.setManagerName(m.getRulerName());
					rulerInfo.setParent(m);
				}
			}

		}
		return rulerInfo;
	}

	public String add(RulerInfo rulerInfo) {
		if(rulerInfo==null)
			return GUtil.FAILE;

		Session session =this.getSession();
		rulerInfo.setLastUpdate((new Timestamp(System.currentTimeMillis())));
		session.save(rulerInfo);
		session.flush();
		
		List<RulerMethod> list = rulerInfo.getMethods();
		if(list!=null){
			for(RulerMethod rm : list){
				rm.setRulerId(rulerInfo.getRulerid());
				session.save(rm);
			}
		}
		return GUtil.SUCCESS;
	}
	
	public String update(int id, RulerInfo rulerInfo) {

		Session session = this.getSession();
		rulerInfo.setRulerid(id);
		rulerInfo.setLastUpdate((new Timestamp(System.currentTimeMillis())));
		session.update(rulerInfo);
		session.flush();
		
		session.createQuery("delete from RulerMethod where rulerId=? ").setInteger(0, id).executeUpdate();

		List<RulerMethod> list = rulerInfo.getMethods();
		if(list!=null){
			for(RulerMethod rm : list){
				rm.setRulerId(rulerInfo.getRulerid());
				session.save(rm);
			}
		}
		return GUtil.SUCCESS;
	}
}
